<?php
/**
 * @link http://www.tintsoft.com/
 * @copyright Copyright (c) 2013 TintSoft LLC
 * @license http://www.tintsoft.com/license/
 */
namespace Leaps\Base;
use Closure;
abstract class Manager {

    /**
     * 应用程序实例
     *
     * @var \Leaps\Support\Application
     */
    protected $app;

    /**
     * 注册自定义驱动的创造者。
     *
     * @var array
     */
    protected $customCreators = array ();

    /**
     * 驱动数组
     *
     * @var array
    */
    protected $drivers = array ();

    /**
     * 创建一个新的管理实例
     *
     * @param \Leaps\Support\Application $app
     * @return void
    */
    public function __construct($app) {
        $this->app = $app;
    }

    /**
     * 获取驱动实例
     *
     * @param string $driver
     * @return mixed
     */
    public function driver($driver = null) {
        $driver = $driver ?  : $this->getDefaultDriver ();
        if (! isset ( $this->drivers [$driver] )) {
            $this->drivers [$driver] = $this->createDriver ( $driver );
        }
        return $this->drivers [$driver];
    }

    /**
     * 创建一个新的驱动实例
     *
     * @param string $driver
     * @return mixed
     */
    protected function createDriver($driver) {
        $method = 'create' . ucfirst ( $driver ) . 'Driver';
        if (isset ( $this->customCreators [$driver] )) {
            return $this->callCustomCreator ( $driver );
        } elseif (method_exists ( $this, $method )) {
            return $this->$method ();
        }
        throw new \InvalidArgumentException ( "Driver [$driver] not supported." );
    }

    /**
     * Call a custom driver creator.
     *
     * @param string $driver
     * @return mixed
     */
    protected function callCustomCreator($driver) {
        return $this->customCreators [$driver] ( $this->app );
    }

    /**
     * Register a custom driver creator Closure.
     *
     * @param string $driver
     * @param Closure $callback
     * @return void
     */
    public function extend($driver, Closure $callback) {
        $this->customCreators [$driver] = $callback;
    }

    /**
     * 得到所有创建的驱动。
     *
     * @return array
     */
    public function getDrivers() {
        return $this->drivers;
    }

    /**
     * 动态调用默认驱动程序实例。
     *
     * @param string $method
     * @param array $parameters
     * @return mixed
     */
    public function __call($method, $parameters) {
        return call_user_func_array ( array ($this->driver (),$method ), $parameters );
    }
}